/*
 * Copyright (c) 2009, Jan Pastor. All Rights Reserved.
 */

package sk.jp.commons.ui;

import java.awt.*;
import javax.swing.*;

import sk.jp.commons.exception.ApplicationException;
import sk.jp.commons.tools.Messages;
import sk.jp.commons.utils.ExceptionUtils;
import sk.jp.commons.utils.StringUtils;

/**
 * Dialog window for presentation exceptions.
 */
public class ExceptionDialog {

    public enum Msg {
        btnDetails("ui.exceptiondialog.btn.details"),//Details
        btnClose("ui.exceptiondialog.btn.close"),//Close
        dlgTitle("ui.exceptiondialog.title"),//Exception
        error("ui.exceptiondialog.error"),//Error
        exclass("ui.exceptiondialog.class"),//Class
        strace("ui.exceptiondialog.strace"),//Stack-Trace
        detailTitle("ui.exceptiondialog.dettitle"),//Exception details
        ;
        //----------------------------------------------------------------------
        private String propKey;
        Msg(String propKey) {
            this.propKey = propKey;
        }
        public String getPropKey() {
            return propKey;
        }
        public String value() {
            return Messages.getMessage(propKey);
        }
    }

    //----------------------------------------------------------------------

    private static final Object[] options = {Msg.btnDetails.value(), Msg.btnClose.value()};

    private ExceptionDialog() {
    }

    //----------------------------------------------------------------------

    /**
     * Presents given exception.
     * @param ownerFrame parent component ({@link Frame} or {@link Dialog}).
     * @param exception exception to present.
     */
    public static void show(Window ownerFrame, Throwable exception){
        try {

            String excMessage = ExceptionUtils.translateException(exception);
            excMessage = wrapText(excMessage);
            int o = JOptionPane.showOptionDialog(ownerFrame,
                                                 excMessage,
                                                 Msg.dlgTitle.value(),
                                                 JOptionPane.OK_CANCEL_OPTION,
                                                 JOptionPane.ERROR_MESSAGE,
                                                 null, options, options[1]);

            if (o == JOptionPane.OK_OPTION) { //detail button pressed
                openDetailDialog(ownerFrame, excMessage, exception);
            }
        } catch (Exception e) {
            throw new ApplicationException("Can't show exception dialog", null,
                                           ExceptionUtils.paramsToMap("exception to show", exception),
                                           e);
        }
    }

    //----------------------------------------------------------------------

    private static String wrapText(String text){
        return StringUtils.wrapText(text, 80, StringUtils.SPLIT_EXT, "\n\t");
    }

    private static void openDetailDialog(Window ownerFrame, String exceptionMessage,
                                         Throwable exception){
        StringBuilder buf = new StringBuilder();

        buf.append("<div style=\"color: Black; font-size: 9px; font-family: sans-serif;\">")
            .append("<b><u>").append(Msg.error.value()).append(":</u></b>\n")
            .append("<b>").append(exceptionMessage).append("</b>\n\n")
            .append("<b><u>").append(Msg.exclass.value()).append(":</u></b>\n")
            .append(ExceptionUtils.getClass(exception)).append("\n\n")
            .append("<b><u>").append(Msg.strace.value()).append(":</u></b>\n")
            .append(ExceptionUtils.getStacktrace(exception)).append("\n\n</div>");

        TextDialog textDialog;
        if(ownerFrame instanceof Frame || ownerFrame == null){
            textDialog = new TextDialog((Frame)ownerFrame, Msg.detailTitle.value(), true);
        }else{
            textDialog = new TextDialog((Dialog)ownerFrame, Msg.detailTitle.value(), true);
        }
        textDialog.setWidth(480);
        textDialog.setHeight(320);
        textDialog.open(buf.toString());
    }

}
